<template>
  <div class="line-container">
    <div id="line-chart" style="height: 100%"></div>
  </div>
</template>

<script setup>
  import { ref, onMounted, onBeforeUnmount } from "vue";
  import { init as chartInit } from "echarts";
  import dayjs from "dayjs";
  import { circleImage, locationImage } from "./echartsImage";
  import mockData from "./mock.js";

  let chartConfig = null;
  let prevItem = null; //上一次选中的点
  let dataList = [];
  // 换气次数最大最小值
  const airChangesNum = ref({
    min: -0.6,
    max: -0.3,
  });
  // 风量最大最小值
  const airVolumeNum = ref({
    min: 2300,
    max: 122300,
  });
  // 根据最大最小值计算图形与页面两边的间距
  const chartPadding = (val) => {
    const { max, min } = val;
    const maxStr = max.toLocaleString();
    const minStr = min.toLocaleString();
    const maxLen = maxStr.length;
    const minLen = minStr.length;
    const len = Math.max(maxLen, minLen);
    return 10 * (len + 1) + 4; //4是白底数字边距
  };

  // 分布类型
  const distributionType = ref({
    //亟需改善
    needImprovement: {
      start: airChangesNum.value.min,
      end: -0.4,
      color: "rgba(245, 80, 71, 1)",
      background: "rgba(245, 80, 71, 0.08)",
    },
    //一般
    sameAs: {
      start: -0.4,
      end: -0.5,
      color: "rgba(242, 159, 0, 1)",
      background: "rgba(242, 159, 0, 0.08)",
    },
    // 良好
    good: {
      start: 220,
      end: 300,
      color: "rgba(20, 196, 196, 1)",
      background: "rgba(20, 196, 196, 0.08)",
    },
    // 出色
    outstanding: {
      start: 300,
      color: "rgba(63, 190, 114, 1)",
      background: "rgba(63, 190, 114, 0.08)",
    },
  });

  // 获取图形配置
  const getChartOption = () => {
    const { needImprovement, sameAs, good, outstanding } =
      distributionType.value;
    const option = {
      legend: {
        show: false,
      },
      tooltip: {
        show: false,
      },
      grid: {
        left: chartPadding(airChangesNum.value),
        top: 80,
        right: chartPadding(airVolumeNum.value),
        bottom: 85,
      },
      xAxis: {
        // type: 'time',
        boundaryGap: false, // 标签不限制在坐标轴上
        axisLine: {
          show: true,
          lineStyle: {
            color: "#8B949E",
          },
        },
        axisLabel: {
          color: "#626C78",
          fontSize: "18px",
          hideOverlap: true,
          formatter: function (val) {
            return dayjs(new Date(val).getTime()).format("YYYY.MM.DD");
          },
        },
        axisTick: {
          show: false,
        },
        data: mockData.map(function (item) {
          return item.name;
        }),
      },
      yAxis: [
        {
          type: "value",
          name: "平均换气次数(次/小时)",
          // min: airChangesNum.value.min,
          // max: airChangesNum.value.max,
          // 根据数据动态显示最大最小值
          min: "dataMin",
          max: "dataMax",
          // 不显示中间数值 --start
          splitNumber: 1,
          interval: Infinity,
          // 不显示中间数值 --end
          nameTextStyle: {
            color: "#626C78",
            fontSize: 18,
            align: "left",
            padding: [0, 0, 0, -chartPadding(airChangesNum.value)],
          },
          splitLine: {
            show: false,
          },
          axisTick: {
            show: false,
          },
          axisLine: {
            show: true,
            symbol: ["none", "arrow"],
            symbolSize: [7, 8],
            lineStyle: {
              color: "#8B949E",
            },
          },
          axisLabel: {
            color: "#626C78",
            fontSize: 18,
            showMinLabel: true, // 显示最小刻度标签
            showMaxLabel: true, // 显示最大刻度标签
          },
        },
        {
          type: "value",
          name: "风量(m³/h)",
          min: airVolumeNum.value.min,
          max: airVolumeNum.value.max,
          nameTextStyle: {
            padding: [0, 100 - chartPadding(airVolumeNum.value), 0, 0],
            color: "#626C78",
            fontSize: 18,
          },
          splitLine: {
            show: false,
          },
          axisLine: {
            show: true,
            symbol: ["none", "arrow"],
            symbolSize: [7, 8],
            lineStyle: {
              color: "#8B949E",
            },
          },
          axisLabel: {
            fontSize: 18,
            color: "#626C78",
            showMinLabel: true, // 显示最小刻度标签
            showMaxLabel: true, // 显示最大刻度标签
          },
        },
      ],
      dataZoom: [
        {
          type: "inside",
        },
        {
          type: "slider",
          backgroundColor: "rgba(255, 255, 255, 0.3)",
          borderColor: "rgba(255, 255, 255, 0.3)",
          textStyle: {
            fontSize: 18,
          },
          labelFormatter: function (value) {
            const time = new Date(dataList[value].name).getTime();
            return dayjs(time).format("YYYY.MM.DD");
          },
        },
      ],
      // 线段着色
      visualMap: {
        show: false, //不显示范围颜色图例
        pieces: [
          {
            gt: needImprovement.start,
            lte: needImprovement.end,
            color: needImprovement.color,
          },
          {
            gt: sameAs.start,
            lte: sameAs.end,
            color: sameAs.color,
          },
          {
            gt: good.start,
            lte: good.end,
            color: good.color,
          },
          {
            gt: outstanding.start,
            color: outstanding.color,
          },
        ],
        outOfRange: {
          color: outstanding.color,
        },
      },
      series: [
        {
          type: "line",
          data: dataList,
          emphasis: {
            scale: 1.33,
          },
          // 标线
          markLine: {
            silent: true,
            symbol: "none", //去掉箭头
            lineStyle: {
              normal: {
                color: "#1B2129",
                type: "dashed",
              },
            },
            data: [
              {
                yAxis: 140,
                name: "整改阀值",
              },
              {
                yAxis: 180,
                name: "诊断阀值",
              },
            ],
            label: {
              normal: {
                position: "insideStartTop",
                textStyle: {
                  color: "#626C78",
                  fontSize: 18,
                  textBorderColor: "#fff",
                  textBorderWidth: 1,
                },
                formatter: function (param) {
                  return param.name;
                },
              },
            },
          },
          // 背景着色
          markArea: {
            silent: true,
            data: [
              [
                {
                  yAxis: needImprovement.start,
                  itemStyle: {
                    color: needImprovement.background,
                  },
                },
                {
                  yAxis: needImprovement.end,
                },
              ],
              [
                {
                  yAxis: sameAs.start,
                  itemStyle: {
                    color: sameAs.background,
                  },
                },
                {
                  yAxis: sameAs.end,
                },
              ],
              [
                {
                  yAxis: good.start,
                  itemStyle: {
                    color: good.background,
                  },
                },
                {
                  yAxis: good.end,
                },
              ],
              [
                {
                  yAxis: outstanding.start,
                  itemStyle: {
                    color: outstanding.background,
                  },
                },
                {
                  yAxis: outstanding.end,
                },
              ],
            ],
          },
        },
        {
          type: "line",
          // 标线数值 换气次数
          markLine: {
            silent: true,
            lineStyle: {
              color: "rgba(0,0,0,0)",
            },
            data: [
              {
                yAxis: 140,
              },
              {
                yAxis: 180,
              },
            ],
            label: {
              padding: [0, 3, 0, 0],
              position: "start",
              textStyle: {
                fontSize: 18,
                color: "#626C78",
                borderRadius: 4,
                padding: 4,
                backgroundColor: "rgba(255, 255, 255, 0.90)",
              },
            },
          },
        },
        {
          // 标线数值 风量
          type: "line",
          markLine: {
            silent: true,
            lineStyle: {
              color: "rgba(0,0,0,0)",
            },
            data: [
              {
                yAxis: 140,
                name: "2300",
              },
              {
                yAxis: 180,
                name: "60000",
              },
            ],
            label: {
              position: "end",
              padding: [0, 0, 0, 3],
              textStyle: {
                fontSize: 18,
                color: "#626C78",
                borderRadius: 4,
                padding: 4,
                backgroundColor: "rgba(255, 255, 255, 0.90)",
              },
              formatter: function (param) {
                return param.name;
              },
            },
          },
        },
      ],
    };
    return option;
  };
  // 适应容器
  const resizeChart = () => {
    if (chartConfig) chartConfig.resize();
  };
  // 选中
  const clickItem = (data) => {
    // 还原上一次选中的样式
    if (prevItem) {
      const prevIndex = dataList.findIndex((x) => x.name === prevItem.name);
      dataList[prevIndex].symbol = circleImage(prevItem.color);
      dataList[prevIndex].symbolSize = 12;
      dataList[prevIndex].symbolOffset = [0, 0];
    }
    const i = dataList.findIndex((x) => x.name === data.name);
    // 设置选中样式
    dataList[i].symbol = locationImage(data.color);
    dataList[i].symbolSize = 32;
    dataList[i].symbolOffset = [0, -16];
    dataList[i].itemStyle = { opacity: 1 };
    prevItem = data;
    chartConfig.setOption({
      series: [
        {
          // 通过饼图表现单个柱子中的数据分布
          data: dataList,
        },
      ],
    });
  };
  // 添加事件监听
  const addListenerChart = () => {
    chartConfig.off("click");
    chartConfig.on("click", (val) => {
      clickItem(val.data);
    });
  };
  // 绘制图形
  const drawChart = () => {
    if (chartConfig) chartConfig.clear();
    const dom = document.getElementById("line-chart");
    console.log(dom);
    if (!dom) return;
    console.log(chartConfig);
    chartConfig = chartInit(dom, null, {
      renderer: "canvas",
      useDirtyRect: false,
    });
    chartConfig.setOption(getChartOption());
    addListenerChart();
    window.addEventListener("resize", resizeChart);
  };

  // 初始化数据
  const initData = () => {
    dataList = mockData.map(function (item) {
      return {
        color: item.color,
        name: item.name,
        value: item.airChanges,
        symbol: circleImage(item.color),
        symbolSize: 12,
        symbolOffset: [0, 0],
        label: {
          normal: {
            show: false,
          },
        },
      };
    });
    drawChart();
  };

  onMounted(() => {
    initData();
  });
  onBeforeUnmount(() => {
    chartConfig = null;
    prevItem = null;
    window.removeEventListener("resize", resizeChart);
  });
</script>
<style lang="less" scoped>
  .line-container {
    height: 100%;
  }
</style>
